package rs.fon.rapidminer.operator.learner.tree;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import rs.fon.rapidminer.process.annotation.Parameter;

import com.rapidminer.example.Attribute;
import com.rapidminer.example.AttributeWeights;
import com.rapidminer.example.Example;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.example.set.SimpleExampleSet;

import rs.fon.rapidminer.operator.learner.tree.SplittedExampleSet;
import com.rapidminer.operator.features.weighting.ChiSquaredWeighting;
import com.rapidminer.operator.IOContainer;
import com.rapidminer.operator.IOObject;
import com.rapidminer.operator.Operator;
import com.rapidminer.operator.OperatorCreationException;
import com.rapidminer.operator.OperatorDescription;
import com.rapidminer.operator.OperatorException;
import com.rapidminer.operator.UserError;
import com.rapidminer.operator.features.weighting.ChiSquaredWeighting;
import com.rapidminer.operator.learner.tree.Benefit;
import com.rapidminer.operator.preprocessing.discretization.BinDiscretization;
import com.rapidminer.parameter.UndefinedParameterError;
import com.rapidminer.parameter.Parameters;
import com.rapidminer.tools.OperatorService;
import com.rapidminer.tools.math.ContingencyTableTools;
import org.apache.commons.math.stat.inference.*;

public class RemoveInsignificantAtributesCategorical extends AbstractRemoveInsignificantAtributes  {

	@Parameter(defaultValue = "0.05", maxValue = "1.0", minValue = "0.0")
	private Double Alpha_Value;

	
	
	private Parameters parameters = null;
	
	@Override
	public Object DoWork(ExampleSet splitted, List<rs.fon.rapidminer.process.Parameter> parameters, int depth, boolean [] attributesForSplitting) throws Exception
	{			
			boolean[] weights = calculateWeights(splitted, depth, attributesForSplitting, parameters);	    		    
		    return weights;	
	}
	
	public boolean[] calculateWeights(ExampleSet exampleSet, int depth,boolean [] attributesForSplitting, List<rs.fon.rapidminer.process.Parameter> parameters) throws Exception {
		
		int nominalAttributes = 0;
		int k=0;
		
		for(Attribute attribute : exampleSet.getAttributes())
		{
			if(attribute.isNominal())
				nominalAttributes++;
		}
		
		//double[] weights = new double[nominalAttributes];
		
		Attribute label = exampleSet.getAttributes().getLabel();
		
		for(Attribute attribute : exampleSet.getAttributes())
		{
			if(attribute.isNominal() && !attribute.equals(label))
			{			
				long [][] matrixForAttribute = getContigencyTable(exampleSet, attribute, depth);
			
				//double weight = ContingencyTableTools.getChiSquaredStatistics(matrixForAttribute, false);
				ChiSquareTestImpl chiTest = new ChiSquareTestImpl();
				double param = Double.parseDouble(parameters.get(0).getXenteredValue());
				boolean accept = chiTest.chiSquareTest(matrixForAttribute,param); //HardKodovan parametar ISPRAVITI!!!!!!
				attributesForSplitting[k] = accept;
				k++;
			}
		}
		
		return attributesForSplitting;	
	}
	
	private long [][] getContigencyTable(ExampleSet exampleSet, Attribute attribute, int depth)
	{
		Attribute label = exampleSet.getAttributes().getLabel();
		List<String> labelCategories = null;
		List<String> attributeCategories = null;
		
		if(depth == 1)
		{
			SimpleExampleSet workingExampleSet = (SimpleExampleSet) exampleSet;
			labelCategories = getAllCategories(workingExampleSet, label);
			attributeCategories = getAllCategories(workingExampleSet, attribute);
		}
		else 
		{ 
			SplittedExampleSet workingExampleSet = (SplittedExampleSet)exampleSet;
			labelCategories = workingExampleSet.getAllCategories(label);
			attributeCategories = workingExampleSet.getAllCategories(attribute);
		}		
		
		int numberOfLabelCategories = labelCategories.size();
		int numberOfAttributeCategories = attributeCategories.size();
		
		long[][] matrix = new long[numberOfAttributeCategories][numberOfLabelCategories];
		
		for(int i = 0; i < numberOfAttributeCategories; i++)
			for(int j = 0; j < numberOfLabelCategories; j++)
			{
				matrix[i][j] = 0;
				
				for(Example example : exampleSet)
				{
				      if(labelCategories.get(j).equals(example.getNominalValue(label)) && attributeCategories.get(i).equals(example.getNominalValue(attribute)))
				    		  matrix[i][j] += 1;
				}
			}
		
		return matrix;
	}
	
	public  LinkedList<String> getAllCategories(ExampleSet exampleSet, Attribute attribute) {
        LinkedList<String> allCategoryList  =  new LinkedList<String>();
   
       
        Iterator<Example> reader = exampleSet.iterator();
       
        while (reader.hasNext()) {
            Example example = reader.next();
            String currentValue = example.getValueAsString(attribute);
            if (!inList(currentValue,allCategoryList))
                allCategoryList.add(currentValue);
        }
       
        //return new SplittedExampleSet(exampleSet, partition);
        return allCategoryList;
    }
	public  boolean inList(String category,List<String> allCategoryList) {
	       
	        for(int i =0; i<allCategoryList.size();i++)
	        {
	            if (allCategoryList.get(i).equals(category))
	                return true;
	         
	        }
	        return false;
	}
}
